package Main;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.StringWriter;
import java.net.URL;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;

import org.apache.oro.text.regex.MalformedPatternException;
import org.apache.oro.text.regex.MatchResult;
import org.apache.oro.text.regex.PatternCompiler;
import org.apache.oro.text.regex.PatternMatcher;
import org.apache.oro.text.regex.PatternMatcherInput;
import org.apache.oro.text.regex.Perl5Compiler;
import org.apache.oro.text.regex.Perl5Matcher;

import Bus.BusStation;
import Bus.TestBusStation;

public class TestEnter {
	public static final String BUS_URL = "http://bus.mapbar.com/beijing/line_list/";
	private static String currentPath = System.getProperty("user.dir");
	private static String beijingBusHtml = "BeijingBus.html";
	private static LogTool logger = null;
	private static final boolean DEBUG = true;
	
	public static void main(String[] args) {	
		logger = new LogTool("FetchBus");
		////抓取车次列表的html，保存在本地BeijingBus.html中
		//String html = fetchHtmlFromUrlAndReturnStr(currentPath + "\\HTML\\", BUS_URL, beijingBusHtml); 
	
		//分析BeijingBus.html，将得到的车次列表写入数据库beijing_bus_list表
		//fetchBusListFromHtml(html);
		
		//读取数据库的beijing_bus_list表，按busName,busUrl抓取所有车次的html，保存在本地BUS文件夹中
		//fetchBusInfoPageFromUrl(); 
		
		//读取本地的BUS文件夹，遍历并分析其中的文件，将数据写入数据库BusLine表
		File f = new File(currentPath + "\\HTML\\BUS\\");
		fetchBusInfoFromHtml(f);
		
		System.out.println("Complete!");
	}
		
	/**
	 * 打印数据库内容，调试用
	 * @param rs
	 */
	public static void printDBData(ResultSet rs){
		ResultSetMetaData rsmd;
		try {
			rsmd = rs.getMetaData();
		
			int j = 0;
			j = rsmd.getColumnCount();
			
			for(int k = 0; k<j; k++){
				System.out.print(rsmd.getCatalogName(k+1));
				System.out.print("\t");
			}
			
			System.out.println();
			
			while(rs.next()){
				for(int i=0;i<j;i++){
					if(rsmd.getColumnName(i+1).equals("running_time")){
						int ii = i+1;						
						System.out.print("[" + convertByteToString(rs.getBytes(ii)) + "]");
						System.out.print("\n");
					}else{
						System.out.print(rs.getString(i+1));
						System.out.print("\t");
					}
				}
				System.out.println();
			}
			
			rs.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * 将byte转化成string
	 * @param b
	 * @return
	 */
	public static String convertByteToString(byte[] b) {
        String str = "";       
		
        for(byte bb : b){
			
	        str += new String(new byte[] {bb});
		}

        return str;
    }
	
	/**
	 * 根据url抓取html页面, 并且返回string
	 * @param url，要抓取的url
	 * @param saveName，保存时的名字
	 * @return
	 */
	private static String fetchHtmlFromUrlAndReturnStr(String outputFolder, String url, String saveName){
		String html = null;
		InputStream in = null;  
		InputStream in2 = null;
		OutputStream out = null; 
				
		try { 			
			// Write data to HTML file			
			URL mUrl = new URL(url);
			in = mUrl.openStream(); 
			out = new FileOutputStream(outputFolder + saveName);
			byte[] buffer = new byte[4096]; 
			int bytes_read; 			
			while((bytes_read = in.read(buffer)) != -1){ 
				out.write(buffer, 0, bytes_read); 
			}
			
			// Write data to String
			in2 = mUrl.openStream(); 
			InputStreamReader inReader = new InputStreamReader(in2); 
	        StringWriter sw = new StringWriter(); 
	        char[] buffer2 = new char[1024]; 
	        int n = 0; 
	        while (-1 != (n = inReader.read(buffer2))) { 
	            sw.write(buffer2, 0, n); 
	        } 

			html = sw.toString();
		}  
		catch (Exception e) { 
			System.err.println(Util.getCurrentTime() + "	Error occurs while fetching HTML page\n" + e);
		} 
		finally {
			try { 
				in.close();
				in2.close();
				out.close(); 
				logger.log("fetch bus " + saveName + " - Done");
			} catch (Exception e) {
				System.err.println(Util.getCurrentTime() + "	Error occurs while closing inputStream/outputStream\n" + e);
				logger.log("fetch bus " + saveName + " - Fail");
			} 			
		}
		
		return html;
	}
	
	/**
	 * 根据url抓取html页面, 并且返回string
	 * @param url，要抓取的url
	 * @param saveName，保存时的名字
	 * @return
	 */
	private static void fetchHtmlFromUrl(String outputFolder, String url, String saveName){
		InputStream in = null;  
		OutputStream out = null; 
				
		try { 			
			// Write data to HTML file			
			URL mUrl = new URL(url);
			in = mUrl.openStream(); 
			out = new FileOutputStream(outputFolder + saveName);
			byte[] buffer = new byte[10240]; 
			int bytes_read; 			
			while((bytes_read = in.read(buffer)) != -1){ 
				out.write(buffer, 0, bytes_read); 
			}
		}  
		catch (Exception e) { 
			System.err.println(Util.getCurrentTime() + "	Error occurs while fetching HTML page\n" + e);
		} 
		finally {
			try { 
				in.close();
				out.close(); 
				logger.log("fetch bus " + saveName + " - Done");
			} catch (Exception e) {
				System.err.println(Util.getCurrentTime() + "	Error occurs while closing inputStream/outputStream\n" + e);
				logger.log("fetch bus " + saveName + " - Fail");
			} 			
		}
	}
	
	/**
	 * 从web文件中，分析得出北京所有的公交线路名称，及该公交线路详情的url地址
	 * 并且写入本地数据库中
	 * @param html，字符串形式的web页面内容
	 */
	public static void fetchBusListFromHtml(String html){	
		System.out.print("fetchBusListFromHtml - running");
		String tag_bus_list = "<ahref=\"http://bus.mapbar.com/beijing/xianlu.*?</a></li>";		
		String noBlankHtml = Util.replaceBlank(html);

		PatternCompiler compiler = new Perl5Compiler();
		PatternMatcher matcher = new Perl5Matcher();
		org.apache.oro.text.regex.Pattern pattern = null;
		try {
			pattern = compiler.compile(tag_bus_list);
		} catch (MalformedPatternException e) {
			e.printStackTrace();
		}
		
		String user = "root";
		String pwd = "root";
		String url = "jdbc:mysql://localhost:3306/bjbus";
		String tableName = "beijing_bus_list";
		String sqlstr;	
		JDBCConnecter mJDBCConnecter = new JDBCConnecter(url, user, pwd);
		mJDBCConnecter.connectDB();
		 
		PatternMatcherInput input = new PatternMatcherInput(noBlankHtml);
		String temp, bus_url, bus_name;
		int i = 0;
		
        while(matcher.contains(input, pattern)) {
        	MatchResult result = matcher.getMatch();
        	temp = result.group(0);	           
            bus_url = getBusUrl(temp);
            bus_name = getBusName(temp);
            
            StringBuilder sb_bus = new StringBuilder();	        
            sb_bus.append(bus_name);
            sb_bus.append(", ");
            sb_bus.append(bus_url);
            sb_bus.append(" | ");
                        
            StringBuilder sb_sql = new StringBuilder();
            sb_sql.append("insert into ");
            sb_sql.append(tableName);
            sb_sql.append("(bus_name,bus_url) ");
            sb_sql.append("values('");
            sb_sql.append(bus_name);
            sb_sql.append("','");
            sb_sql.append(bus_url);
            sb_sql.append("');");
            sqlstr = sb_sql.toString();

    		int ret = mJDBCConnecter.executeInsert(sqlstr);
    		
    		if(DEBUG) logger.log(sb_bus.toString() + ret);
            i++;
        }
        
        mJDBCConnecter.closeDB();
        
        if(DEBUG) logger.log("总共获取到了" + i + "条线路");
        System.out.println(" - Done");
        System.out.println("Total bus number " + i);
	}
	
	/**
	 * 从字符串中，分析出公交线路的url
	 * @param busInfo, <ahref="http://bus.mapbar.com/beijing/xianlu/961lu/"target=_blacktitle="">961路</a></li> 
	 * @return String, http://bus.mapbar.com/beijing/xianlu/zhuanxian20lu/
	 */
	private static String getBusUrl(String busInfo){
		int start = busInfo.indexOf("http");
		int end = busInfo.indexOf("\"target");
		
		return busInfo.substring(start, end);
	}
	
	/**
	 * 从字符串中，分析出公交线路的名字
	 * @param busInfo，<ahref="http://bus.mapbar.com/beijing/xianlu/961lu/"target=_blacktitle="">961路</a></li>
	 * @return String， 961路
	 */
	private static String getBusName(String busInfo){
		int start = busInfo.indexOf(">");
		int end = busInfo.indexOf("</a>");
		String name = busInfo.substring(start+1, end);
				
		return name.replace("...", ""); 
	}
	

	private static void fetchBusInfoPageFromUrl(){
		System.out.println("fetchBusInfoPageFromUrl - running");
		if(DEBUG) logger.log("fetchBusInfoPageFromUrl()");
		
		String output = currentPath + "\\HTML\\BUS\\";
		//从本地数据库中读取出所有名字和URL
		String user = "root";
		String pwd = "root";
		String dbUrl = "jdbc:mysql://localhost:3306/bjbus";
		String sqlstr = "select bus_name,bus_url from beijing_bus_list where id>=1159;";	
		
		JDBCConnecter mJDBCConnecter = new JDBCConnecter(dbUrl, user, pwd);
		mJDBCConnecter.connectDB();
		ResultSet rs = mJDBCConnecter.executeQuery(sqlstr);
		
		try{
			rs.last();
			int count= rs.getRow();
			System.out.print("Total read " + count + " from database");
			rs.beforeFirst();
		}catch(SQLException e){
			e.printStackTrace();
		}
				
		try {
			while(rs.next()){
				//根据url从网上抓取html页面，保存在本地
				fetchHtmlFromUrl(output, rs.getString(2), rs.getString(1));
			}			
			rs.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		mJDBCConnecter.closeDB();
		System.out.println(" - Done");
	}
		
	private static void fetchBusInfoFromHtml(File file){
		//TODO:分析公交线路的html文件，得出busLine的信息
		if(!file.isDirectory()){
			System.out.println("fetchBusLineFromHtml() - error, not folder");
			return;
		}
		
		File []fileList = file.listFiles();
		int fileNumber = fileList.length;
		
		for(int i=0; i<fileNumber; i++){
			String busName = fileList[i].getName();
			
			//过滤掉地铁线路
			if(busName.indexOf("地铁") > -1){
				continue;
			}
			
			//过滤掉近郊铁路S2
			if(busName.indexOf("铁路") > -1){
				continue;
			}
			
			//过滤掉 顺义34路区间 错误的数据
			if(busName.indexOf("顺义34路区间") > -1){
				continue;
			}
			
			String busInfo = Util.loadAFileToStringDE1(fileList[i]);
			busInfo = Util.replaceBlank(busInfo);
			
			//System.out.print(busName + busInfo.length());
			//TODO:在类中分析，且写入数据库
			//BusLine mBusLine = new BusLine(busName, busInfo);
			
			
			//TODO:在类中分析，且写入数据库
			//BusStation mBusStation = new BusStation(busName, busInfo);
			TestBusStation mBusStation = new TestBusStation(busName, busInfo);
			
			//mBusLine = null;
			//mBusStation = null;
		}
		
	}
	
	
	
	

}
